Conditional Jumps (IF - ELSEIF - ELSE _ENDIF)

These are handled at the start of DOLINE by the following code:

  i1:= StringType[AtString]; {A label at start of line}
  Vartext:= '';
  if i1 = 1 then  {First deal with jumps and subroutine definitions.}
    begin { A system command}
        case Round(StringValue[AtString]) of
       20:begin {if}
           IfLevel:= succ(IfLevel); {move down to next if-stack level}
           with IfStatus[IfLevel] do
           begin
            SkipOn:= SkipLine; {save current skip state}
            if not SkipOn then { Skip remainder of section if Skip in force}
            begin
             if StringType[AtString+1] in [3 .. 6] then
             begin   {check line syntax}
              if (Round(StringValue[Atstring+1])=1) then
              begin
               DoneIf:= True;
               SkipLine:= False;
              end else SkipLine:= True;
             end else begin  {Error in line syntax}
               Messagedlg('D8: Error in If Statement condition',
                           mtError,[mbabort],0);
               Disaster:= True;
             end; {if StringType}
            end; {Not SkipOn}
           end; {With IfStatus}
          end; {if}
       21:begin {elseif}
           With IfStatus[IfLevel] do
           begin
            If not (SkipOn or DoneIf)  then
            begin
             if StringType[AtString+1] in [3 .. 6] then
             begin  {Syntax check O.K.}
              if (Round(StringValue[Atstring+1])=1) then
              begin
               SkipLine:= False;
               DoneIf:= True;
              end else SkipLine:= True;
              {SkipLine will be true at this point if DoneIf already set}
             end else begin
              Messagedlg('D9:Error in ElseIf Statement condition',
                         mtError,[mbabort],0);
              Disaster:= True;
             end;
            end else SkipLine:= True; {not SkipOn}
           end; {IfStatus}
          end;  {elseif}
       22:begin {else}
           with IfStatus[IfLevel] do
           begin
            If  not (SkipOn or DoneIf) then
            begin
             If (NumOfSubStrings>=(AtString+1))
                 and (StringText[AtString+1] = 'if')
                 and (StringType[AtString+2] in [3 .. 6]) then
             begin {case of ELSE followed by IF}
              if (Round(StringValue[Atstring+2])=1) then
              begin
                SkipLine:= False;
                DoneIf:= True;
              end else SkipLine:= True;;
             end else if (NumOfsubStrings> (AtString+1)) then
             begin {case of ELSE followed by something else}
              if Messagedlg('D10: Ignor Statement following ELSE ?',
                        mtWarning,[mbabort,mbOK],0)= mrAbort
              then begin
               Disaster:= True;
               Exit;
              end;
             end else if NumOfSubStrings<=(AtString+1) then
              SkipLine:= False; {Simple ELSE statement}
            end else SkipLine:= True; { Not (SkipOn or DoneIf )  }
          end; {IfStatus}
          end;
       23:begin {endif}
             SkipLine:= IFStatus[IfLevel].SkipOn;
             IfStatus[IfLevel].DoneIf:= False;
             IfLevel:= Pred(IfLevel);
             if IfLevel<0 then
             begin
               Messagedlg('D11 Error in nesting IF statements',mtError,
                  [mbAbort],0);
               Disaster:= True;
               Exit;
             end;
          end;
       end;{case StringType}
  end;
 if not Skip then begin {Non-System commands}

 To explain the operation of this code we first note that conditional 
statements involve skipping part of the source listing. However, it is
essential that the ELSE or ENDIF statement at the end of the conditional 
section is not skipped, so these statements must be excluded from the 
skip operation. Hence they are dealt with in a special CASE statement 
at the start of DOLINE before the SKIP operation is invoked. A separate 
global variable SkipLine is also used. (This may not be necessary - 
but this needs checking!) As it stands, SkipLine is set during a call to
DOLINE and is then fed back as the value of SKIP at the next call to
DOLINE, effectively delaying its operation by one line of source listing.

To allow for nested conditional statements a stack structure is used, 
set up as the array IFSTATUS[IFLEVEL]. This is an array of IFRECORDs,
with each record holding two Boolean variables, SKIPON and DONEIF. 

When an IF statement is encountered we increment IFLEVEL and save the 
present status of SKIPLINE  in SKIPON.
If SKIPON is true this means that we are already inside a conditional 
section that is being skipped, so the If statement is ignored. Otherwise 
the next input on the line is examined. This should be a Boolean expression 
which has already been evaluated by the procedure ANALYSE in unit GLETOOLS 
while the current line was being parsed. If the condition is true the value
1 is found and this then turns skip on at this point.

When an ELSEIF statement is encountred the settings of the current IFSTATUS 
record are examined. If the preceeding section was active, or we are already 
in a skip section the next section must be skipped. irrespective of the 
outcome of the logical test at this point. If the previous IF test had 
failed and we are not inside a block being skipped the current test is 
examined and if successfull the local level determined by DONEIF is 
altered.

Else Statements are very similar, except that no local test is involved.
Note that both of these tests do not change the IFLEVEL

Finally, an ENDIF will turn off skip and the local level (DONEIF true)
and decrement the IFLEVEL.
 